<template>
  <div class="selectContainer">
    <div class="left">
      <div v-for="(express, index) in expressionList" :key="index" class="expItem">
        <template v-if="index">
          <el-button>或</el-button>
        </template>
        <el-input :disabled="true" v-model="express.value" />
        <el-button v-if="!express.isEdit" icon="Edit" @click="handleExpressionEdit(index)" />
        <el-button icon="minus" @click="handleExprssionDel(index)" />
      </div>
    </div>
    <div class="right">
      <div class="editor">
        <el-input v-model="curExpression" />
        <template v-if="curEditIdx == -1">
          <el-button icon="Plus" @click="handleExpressionAdd" />
        </template>
        <template v-else>
          <el-button icon="Check" @click="handleExpressionEditDone" />
          <el-button icon="Close" @click="handleExpressionEditCancel" />
        </template>
      </div>
      <div class="selector">
        <el-radio-group v-model="curTableType" @change="handleTableTypeChange">
          <el-radio-button v-for="btn in ButtonGroup" :key="btn.value" :label="btn.label" :value="btn.value" />
        </el-radio-group>
        <el-table :data="tableList" height="400" max-height="400">
          <el-table-column v-for="col in TableColumnSetting[curTableType]" :label="col.label" :prop="col.value" :key="col.value" align="center" min-width="200"></el-table-column>
          <el-table-column>
            <template #default="scope">
              <el-button link type="primary" @click="handleExpressionInsert(scope.row.expression)">追加</el-button>
            </template>
          </el-table-column>
        </el-table>
        <pagination v-show="pageObj.total > 0" :total="pageObj.total" v-model:page="pageObj.pageNum" v-model:limit="pageObj.pageSize" @pagination="getList(curTableType)" />
      </div>
    </div>
  </div>
</template>

<script lang="ts">
import { defineComponent, onMounted } from 'vue';
import { ref, watch } from 'vue';
import { ButtonGroup, TableColumnSetting, StarterTableList, ParamTableList } from '../../config/assignee';
import { listPage as userList } from '@base/api/base/user';
import { listCompany as compList } from '@base/api/base/company';
import { listDept as deptList } from '@base/api/base/dept';
import { listRole as roleList } from '@base/api/base/role';

interface Expression {
  value: string;
  isEdit: Boolean;
}

interface Pagination {
  pageNum: number;
  pageSize: number;
  total: number;
}

export default defineComponent({
  name: 'AssgineeSelector',
  props: {
    modelValue: {
      type: Array,
      default: () => []
    }
  },
  emits: ['update:modelValue'],
  setup(props, { emit }) {
    const curExpression = ref<string>('');
    const curEditIdx = ref<number>(-1); // 记录当前编辑项索引
    const tableList = ref<Array<any>>([]);
    const pageObj = ref<Pagination>({
      pageNum: 1,
      pageSize: 10,
      total: 0
    });
    const expressionList = ref<Array<Expression>>([]);
    const curTableType = ref<string>('company');

    const handleExpressionAdd = () => {
      if (curExpression.value) {
        expressionList.value.push({ value: curExpression.value, isEdit: false });
        handleResetExpression();
      }
    };

    const handleExprssionDel = (index: number) => {
      expressionList.value.splice(index, 1);
      handleResetExpression();
    };

    const handleExpressionEdit = (index: number) => {
      handleResetExpression();
      curExpression.value = expressionList.value[index].value;
      curEditIdx.value = index;
      expressionList.value[index].isEdit = true;
    };

    const handleExpressionEditDone = () => {
      expressionList.value[curEditIdx.value].value = curExpression.value;
      handleResetExpression();
    };

    const handleExpressionEditCancel = () => {
      handleResetExpression();
    };

    const handleExpressionInsert = (exp: string) => {
      if (!curExpression.value) {
        curExpression.value = exp;
      } else {
        curExpression.value = curExpression.value + ' AND ' + exp;
      }
    };

    const handleResetExpression = () => {
      curEditIdx.value = -1;
      curExpression.value = '';
      expressionList.value.map((item) => (item.isEdit = false));
    };

    const handleResetPage = () => {
      pageObj.value = {
        pageNum: 1,
        pageSize: 10,
        total: 0
      };
    };

    const getUserList = () => {
      userList(pageObj.value).then((res: any) => {
        tableList.value = res.data.list.map((item: any) => {
          item.expression = `U("${item.userId}")`;
          return item;
        });
        pageObj.value.total = res.data.total;
      });
    };

    const getCompList = () => {
      compList(pageObj.value).then((res: any) => {
        tableList.value = res.data.map((item: any) => {
          item.expression = `C("${item.companyCode}")`;
          return item;
        });
        // pageObj.value.total = res.data.total;
      });
    };

    const getDeptList = () => {
      deptList(pageObj.value).then((res: any) => {
        tableList.value = res.data.map((item: any) => {
          item.expression = `D("${item.deptCode}")`;
          return item;
        });
        // pageObj.value.total = res.data.total;
      });
    };

    const getRoleList = () => {
      roleList(pageObj.value).then((res: any) => {
        tableList.value = res.data.list.map((item: any) => {
          item.expression = `R("${item.roleKey}")`;
          return item;
        });
        pageObj.value.total = res.data.total;
      });
    };

    const getList = (value: string) => {
      switch (value) {
        case 'company':
          getCompList();
          break;
        case 'dept':
          getDeptList();
          break;
        case 'user':
          getUserList();
          break;
        case 'role':
          getRoleList();
          break;
        case 'starter':
          tableList.value = StarterTableList;
          break;
        case 'pp':
          tableList.value = ParamTableList;
          break;
      }
    };

    const handleTableTypeChange = (value: string) => {
      handleResetPage();
      getList(value);
    };

    onMounted(() => {
      handleTableTypeChange(curTableType.value);
    });

    watch(
      () => props.modelValue,
      (newVal: any) => {
        expressionList.value = newVal;
      },
      {
        immediate: true,
        deep: true
      }
    );

    watch(
      () => expressionList.value,
      (newVal: any) => {
        emit('update:modelValue', newVal);
      },
      {
        deep: true
      }
    );

    return {
      curExpression,
      curEditIdx,
      tableList,
      ButtonGroup,
      TableColumnSetting,
      curTableType,
      expressionList, // 表达式列表
      pageObj,
      getList,
      handleExpressionAdd,
      handleExprssionDel,
      handleTableTypeChange,
      handleExpressionInsert,
      handleExpressionEdit,
      handleExpressionEditDone,
      handleExpressionEditCancel
    };
  }
});
</script>

<style lang="scss" scoped>
.selectContainer {
  width: 100%;
  height: auto;
  display: flex;
  gap: 10px;

  .left {
    width: 40%;

    .expItem {
      display: flex;
      margin: 4px 0;
    }
  }

  .right {
    width: 60%;
    display: flex;
    flex-direction: column;
    gap: 20px;

    .editor {
      width: 100%;
      display: flex;
    }

    .selector {
      width: 100%;
    }
  }
}
</style>